初始化
glfwInit():初始化GLFWglfwWindowHint():设置窗口版本glfwCreateWindow():新建一个窗口glfwGetFramebufferSize():获得实际占用的帧缓存大小glfwMakeContextCurrent():指定当前线程所使用的上下文glViewport():设置视口的大小glfwWindowShouldClose():检测窗口是否关闭glfwPollEvents():检查并处理与窗口、键盘、鼠标等相关的所有事件,并触发相应的回调函数glClearColor():清空颜色缓冲区,并设置颜色glClear():清空屏幕,并给每个像素画上背景色glfwSwapBuffers():打开双缓存模式glfwTerminate():关闭GLFW
着色器
设置顶点
GLfloat vertices_1[] =
{
0.0f, 0.5f, 0.0f, // 上顶点
-0.5f, -0.5f, 0.0f, // 左顶点
0.5f, -0.5f, 0.0f, // 右顶点
};### 编写顶点着色器
- 设置顶点着色器源码(后面详细讲解)
// 顶点着色器
const GLchar* vertexCode_1 = "#version 330 core\n" // 3.30版本(版本申明)
"layout(location = 0) in vec3 position_1;\n" // 三个浮点数 vector 向量表示位置。position是变量,并储存了这三个向量
"void main()\n"
"{\n"
"gl_Position = vec4(position_1, 1.0f);\n" // 核心函数(位置信息赋值)
"}\n";
glCreateShader():创建顶点着色器对象glShaderSource():将着色器源码附加到着色器对象上glCompileShader():编译着色器glGetShaderiv():获取编译状态glGetShaderInfoLog():获取错误消息
编写片元着色器
- 过程和编写顶点着色器相同
const GLchar* fragmentCode_1 = "#version 330 core\n" // 版本信息3.3
"out vec4 FragColor_1;\n" // 输出是四个浮点数构成的一个向量 RGB+aerfa
"void main()\n"
"{\n"
"FragColor_1 = vec4(0.5f, 0.75f, 0.25f, 1.0f);\n" // 核心函数(颜色信息赋值)
"}\n";
GLuint fragmentShader_1 = glCreateShader(GL_FRAGMENT_SHADER); // 创建片元着色器对象
glShaderSource(fragmentShader_1, 1, &fragmentCode_1, NULL); // 将片元着色器的内容传进来
glCompileShader(fragmentShader_1); // 编译顶点着色器
GLint flag; // 用于判断编译是否成功的标识符
GLchar infoLog[512]; // 我用的512个字符来装错误信息(如果出错了的话)
glGetShaderiv(fragmentShader_1, GL_COMPILE_STATUS, &flag); // 获取编译状态
if( !flag )
{
glGetShaderInfoLog(fragmentShader_1, 512, NULL, infoLog); // 如果出错,用 glGetShaderInfoLog函数 来获取错误消息
cout<<"ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n"<<infoLog<<endl;
}编写着色器程序
glCreateProgram():创建着色器程序对象glAttachShader():附加着色器对象glLinkProgram():链接已附加着色器glGetProgramiv():检测链接着色器程序是否成功glDeleteShader():删除着色器对象glUseProgram():激活着色器程序
设置顶点数组对象(VAO)
glGenVertexArrays():创建顶点数组对象,存储了顶点数据的格式以及顶点数据所需的 VBO 对象的引用glBindVertexArray():绑定顶点数组对象,传入0解绑
设置顶点缓冲对象(VBO)
glGenBuffers():创建顶点缓冲对象glBindBuffer():绑定顶点缓冲对象类型glBufferData():复制数据到缓冲内存, 即顶点数据传输到 GPU 的显存中,传入0解绑
设值索引缓冲对象(EBO)
- glBindBuffer() 需要绑定到 GL_ELEMENT_ARRAY_BUFFER 目标上,并使用 glDrawElements() 进行绘制
链接顶点属性
glVertexAttribPointer():定义顶点属性, 设定了如何从顶点缓冲区中读取数据,以及这些数据的格式glEnableVertexAttribArray():启用顶点属性
绘制图形
glDrawArrays():使用当前已激活着色器绘制图元
GLSL
模板结构
- 版本声明
- 定义输入输出变量
- 定义uniform函数
- 定义main函数
向量结构
| 类型 | 含义 |
|---|---|
vec+n | 包含n个 float 分量的向量 |
bvec+n | 包含n个 bool 分量的向量 |
ivec+n | 包含n个 int 分量的向量 |
uvec+n | 包含n个 unsigned int 分量的向量 |
dvec+n | 包含n个 double 分量的向量 |
- 通过链操作符 +
.x.y.z.w来访问第1、2、3、4个分量
着色器的输入输出
- 顶点着色器的输入来自顶点数据,使用
layout (location = 0)来链接 - 片段着色器的输入来自顶点着色器的输出,要确保片段着色器的输入变量和顶点着色器的输出变量相同,OpenGL就会把他们链接一起
uniform函数
功能
- 从CPU中的应用向GPU中的着色器发送数据,从而能够在运行阶段控制着色器
特点
- 全局性:uniform 变量必须在每个着色器程序对象中都是独一无二的,而且它可以被着色器程序的任意着色器在任意阶段访问
- 持久性:无论把 uniform 值设置成什么,uniform 会一直保存它们的数据,直到它们被重置或更新。
着色器类
- 私有成员变量:顶点着色器、片段着色器
- 公共成员变量:着色器程序
- 构造函数:Shader(const GLchar *vertexPath, const GLchar *fragmentPath)
- 读取参数中传入的用GLSL编写的着色器源码,并转化为char数组
- 编译顶点和片段着色器
- 链接着色器程序
- 删除顶点和片段着色器
- 析构函数:~Shader
- 公共成员方法:激活着色器程序
Last updated on